package common.util.validator;

import org.hibernate.validator.HibernateValidator;
import org.springframework.util.CollectionUtils;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.executable.ExecutableValidator;
import javax.validation.groups.Default;
import java.util.Set;
import java.util.StringJoiner;

/**
 * 参数校验器工厂
 *
 * @author yuanqinglong
 * @since 2021/2/26 17:31
 */
public class ValidatorFactoryUtils {
    /**
     * 快速失败校验器，有一个校验未通过直接返回错误 不在继续校验
     */
    private static final Validator VALIDATOR_FAIL_FAST = Validation.byProvider(HibernateValidator.class).configure().failFast(true).buildValidatorFactory().getValidator();

    /**
     * 返回全部的校验未通过错误提示
     */
    private static final Validator VALIDATOR = Validation.buildDefaultValidatorFactory().getValidator();


    public static Validator getValidatorFailFast() {
        return VALIDATOR_FAIL_FAST;
    }


    public static Validator getValidator() {
        return VALIDATOR;
    }

    /**
     * 快速失败校验，获取校验方法单个参数的校验器
     *
     * @return 参数校验器
     */
    public static ExecutableValidator getExecutableFastFailValidator() {
        return getValidatorFailFast().forExecutables();
    }


    /**
     * 获取校验方法单个参数的校验器
     *
     * @return 参数校验器
     */
    public static ExecutableValidator getExecutableValidator() {
        return getValidator().forExecutables();
    }

    /**
     * 快速失败校验，有一个校验未通过直接返回错误
     *
     * @param o     参数
     * @param group 组
     * @return 错误信息
     */
    public static String fastFailValidator(Object o, Class<?>... group) {
        Set<ConstraintViolation<Object>> validate = getValidatorFailFast().validate(o, group);
        for (ConstraintViolation<Object> tConstraintViolation : validate) {
            return tConstraintViolation.getMessage();
        }
        return null;
    }

    /**
     * 校验完全部字段返回所有未通过错误
     *
     * @param o     参数
     * @param group 组
     * @return 错误信息
     */
    public static String validator(Object o, Class<?> group) {
        Set<ConstraintViolation<Object>> validate = getValidator().validate(o, group);
        if (!CollectionUtils.isEmpty(validate)) {
            StringJoiner stringJoiner = new StringJoiner("、", "[", "]");
            for (ConstraintViolation<Object> tConstraintViolation : validate) {
                stringJoiner.add(tConstraintViolation.getMessage());
            }
            return stringJoiner.toString();
        }
        return null;
    }


    /**
     * 校验完全部字段返回所有未通过错误
     *
     * @param o 参数
     * @return 错误信息
     */
    public static String fastFailValidator(Object o) {
       return fastFailValidator(o, Default.class);
    }


    /**
     * 校验完全部字段返回所有未通过错误
     *
     * @param o 参数
     * @return 错误信息
     */
    public static String validator(Object o) {
        return validator(o, Default.class);
    }


}
